package com.czy.utils;

import com.czy.common.exception.CustomException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 *
 * month 从0开始
 * day 从1开始
 * @Author: czy
 * @Date: 2021/3/29
 */
public final class DateUtil {
    private DateUtil() {}
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(0);
        int year = 2022;
        int month = 3;
        LocalDate firstWorkDay = LocalDate.of(2022,2,24);//第一天工作时间

        LocalDate firstDay = LocalDate.of(year, month, 1);
        LocalDate lastDay = firstDay.with(TemporalAdjusters.lastDayOfMonth());

        int firstRest = 2;//第一天休星期几
        int secondRest = 3;
        while (true){
            int week = firstDay.getDayOfWeek().getValue();
            long differ =firstDay.toEpochDay()-firstWorkDay.toEpochDay();
            String text = "休息";
            long x = differ/7;
            if (week == firstRest || week == secondRest){
                text = "休息";
            }else {
                text = "上班";
            }
            System.out.println(firstDay.toString() + " 星期"+week+" 相隔天数: "+differ +" "+ text+x);
            firstDay = firstDay.plusDays(1);
            if (lastDay.compareTo(firstDay) <0){
                break;
            }
            // 计算周几休息
            if (x % 3==0 && !list.contains(x)){
                list.add(Integer.valueOf(3));
                firstRest += 1;
                secondRest += 1;
                if (firstRest==8){
                    firstRest = 1;
                }
                if (secondRest==8){
                    secondRest = 1;
                }
            }
            System.out.println("星期"+firstRest +" 和星期"+secondRest+" 休息");
        }
    }

    public static final String PATTERN_DATE_SHORT = "yyyyMMdd";
    public static final String PATTERN_DATE_MS = "yyyyMMddHHmmss";
    public static final String PATTERN_DATE_HH = "yyyyMMddHH";
    public static final String PATTERN_DATE = "yyyy-MM-dd";

    public static final String PATTERN_MONTH = "yyyy-MM";

    public static final String PATTERN_DATE_TIME_MS = "yyyy-MM-dd HH:mm:ss";

    public static final String PATTERN_DATE_TIME = "yyyy-MM-dd HH:mm:ss";

    public static final String PATTERN_DATE_MINUTES = "yyyy-MM-dd HH:mm";

    public static final String PATTERN_DATE_HOURS = "yyyy-MM-dd HH";

    public static final String PATTERN_DATE_TIME_SHORT = "yyyy-MM-dd-HH-mm-ss";

    public static String calendarToDateStr(Calendar calendar){
        Date time = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE_TIME_MS);
        return simpleDateFormat.format(time);
    }

    public static String calendarToDateStr(Calendar calendar,String pattern){
        Date time = calendar.getTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(time);
    }

    /**
     * 获取当前时间日期(未格式化)
     * @return  Wed May 22 15:52:10 CST 2019
     */
    public static Date getDate(){
        Calendar instance = Calendar.getInstance();
        return instance.getTime();
    }

    /**
     * 获取当前时间日期(格式化后的)
     * @return  2019-05-22 16:01:34
     */
    public static String getCurrentDateTime(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE_TIME_MS);
        String formatDate = simpleDateFormat.format(getDate());
        return formatDate;
    }

    /**
     * 获取当前时间日期(格式化后的)
     * @return  2019-05-22
     */
    public static String getCurrentDate(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE);
        String time = simpleDateFormat.format(getDate());
        return time;
    }

    /**
     * 获取当前时间日期(格式化后的)
     * @return  2019-05-22
     */
    public static String getCurrentDate(String format){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        String time = simpleDateFormat.format(getDate());
        return time;
    }

    /**
     * 解析字符串形式的日期
     * @param time
     * @return  Wed May 22 16:01:34 CST 2019
     */
    public static Date parseDate(String time){
        Date parseDate=null;
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DATE_TIME_MS);
            parseDate = simpleDateFormat.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parseDate;
    }

    public static Date parseDate(String time,String pattern){
        Date parseDate=null;
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
            parseDate = simpleDateFormat.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parseDate;
    }

    /**
     * 获取当前时间戳
     * @return  1558511684484
     */
    public static String getCurrentDateStr(){
        return String.valueOf(getDate().getTime());
    }

    /**
     * 获取年
     * @return
     */
    public static int getYear(){
        return Calendar.getInstance().get(Calendar.YEAR);
    }

    public static int getYear(String date){
        Calendar instance = Calendar.getInstance();
        instance.setTime(DateUtil.parseDate(date,DateUtil.PATTERN_DATE));
        return instance.get(Calendar.YEAR);
    }

    /**
     * 获取月
     * @return
     */
    public static int getMonth(){
        return Calendar.getInstance().get(Calendar.MONTH)+1;
    }

    public static int getMonth(String date){
        Calendar instance = Calendar.getInstance();
        instance.setTime(DateUtil.parseDate(date,DateUtil.PATTERN_DATE));
        return instance.get(Calendar.MONTH)+1;
    }

    /**
     * 获取月中的天
     * @return
     */
    public static int getDayOfMonth(){
        return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取月中的天
     * @return
     */
    public static int getDayOfMonth(String date){
        Calendar instance = Calendar.getInstance();
        instance.setTime(DateUtil.parseDate(date,DateUtil.PATTERN_DATE));
        return instance.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取星期
     * @return
     */
    public static String getDayOfWeek(){
        String[] weeks = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
        int i = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)-1;
        return weeks[i];
    }

    /**
     * 获取小时数
     * @param date
     * @return
     */
    public static int getHour(Date date){
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取分钟数
     * @param date
     * @return
     */
    public static int getMinute(Date date){
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 月中的第几个星期
     * @return
     */
    public static int getWeekOfMonth(){
        return Calendar.getInstance().get(Calendar.WEEK_OF_MONTH)-1;
    }

    /**
     * 校验日期格式是否正确
     * @param checkDate
     * @param pattern yyyy-MM-dd HH:mm
     * @return 1:格式正确  -1:格式错误
     */
    public static int checkDateValid(String checkDate,String pattern){
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        try {
            Date date = format.parse(checkDate);
            String str = format.format(date);
            if (str.equals(checkDate)){
                return 1;
            }else{
                return -1;
            }
        } catch (ParseException e) {
            e.printStackTrace();
            return -1;
        }
    }

    /**
     * 计算日期偏移量
     * @param dateStr
     * @param offSet 偏移量 正数则往后加相应天数   负数则往前减相应天数
     * @return
     */
    public static String dateOffSet(String dateStr,int offSet){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        //取今天日期,如果日期类型为String类型,可以使用df.parse()方法,转换为Date类型
        Date parse = null;
        try {
            parse = df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parse);
        //实现日期偏移操作
        calendar.add(Calendar.DATE, offSet);
//        System.out.println("偏移后的日期为:" + df.format(calendar.getTime()));
        return df.format(calendar.getTime());
    }

    /**
     * 计算日期偏移量
     * @param dateStr
     * @param offSet 偏移量 正数则往后加相应天数   负数则往前减相应天数
     * @return
     */
    public static String dateOffSet(String dateStr,String pattern,int offSet){
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        //取今天日期,如果日期类型为String类型,可以使用df.parse()方法,转换为Date类型
        Date parse = null;
        try {
            parse = df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parse);
        //实现日期偏移操作
        calendar.add(Calendar.DATE, offSet);
//        System.out.println("偏移后的日期为:" + df.format(calendar.getTime()));
        return df.format(calendar.getTime());
    }

    public static long calculateBetweenDays(String date1,String date2){
        long days = ChronoUnit.DAYS.between(LocalDate.of(getYear(date1), getMonth(date1),getDayOfMonth(date1)),LocalDate.of(getYear(date2), getMonth(date2),getDayOfMonth(date2)));
        return days;
    }

    public static String timeOffSet(String dateStr,int offSet){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //取今天日期,如果日期类型为String类型,可以使用df.parse()方法,转换为Date类型
        Date parse = null;
        try {
            parse = df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parse);
        //实现日期偏移操作
        calendar.add(Calendar.HOUR, offSet);
//        System.out.println("偏移后的日期为:" + df.format(calendar.getTime()));
        return df.format(calendar.getTime());
    }


    /**
     * 日期格式化
     * @param date
     * @param pattern
     * @return
     */
    public static String dateFormat(String date,String pattern){
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        String format="";
        try {
            Date parse = df.parse(date);
            format = df.format(parse);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return format;
    }

    /**
     * 校验两个时间段是否有交叉
     * @param s1 时间段1开始时间
     * @param e1 时间段1结束时间
     * @param s2 时间段2开始时间
     * @param e2 时间段2结束时间
     * @param pattern 日期格式
     * @return 有交集返回true 没交集返回false
     */
    public static boolean checkDateIntersection(String s1,String e1,String s2,String e2,String pattern){
        long dateS1 = DateUtil.parseDate(s1, pattern).getTime();
        long dateE1 = DateUtil.parseDate(e1, pattern).getTime();

        long dateS2 = DateUtil.parseDate(s2, pattern).getTime();
        long dateE2 = DateUtil.parseDate(e2, pattern).getTime();
        if (dateS1>dateE1 || dateS2>dateE2){
            throw new CustomException("开始时间不能比结束时间大");
        }
        if (dateE1<=dateS2 || dateS1>=dateE2){
            System.out.println("无交集");
            return false;
        }
        System.out.println("有交集");
        return true;
    }

    /**
     * 日期相减
     * @param dateStr1 日期字符串1
     * @param dateStr2  日期字符串2
     * @param pattern 日期格式
     * @return
     */
    public static long dateSubtract(String dateStr1,String dateStr2,String pattern){
        long date1 = DateUtil.parseDate(dateStr1, pattern).getTime();
        long date2 = DateUtil.parseDate(dateStr2, pattern).getTime();
        return date1-date2;
    }

    /**
     * 设置时间的小时和分钟
     * @param time
     * @param hour
     * @param minute
     * @return
     */
    public static String setTime(String time,Integer hour,Integer minute){
        Date date = DateUtil.parseDate(time, DateUtil.PATTERN_DATE);
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        instance.set(Calendar.HOUR_OF_DAY,hour);
        instance.set(Calendar.MINUTE,minute);
        return DateUtil.calendarToDateStr(instance,DateUtil.PATTERN_DATE_MINUTES);
    }

    /**
     * 获取两个日期之间的天数集合
     * @param startTime
     * @param endTime
     * @return
     */
    public static ArrayList<String> getDaysBetweenDate(String startTime, String endTime){
        String startDate=DateUtil.dateFormat(startTime, DateUtil.PATTERN_DATE);
        String endDate=DateUtil.dateFormat(endTime, DateUtil.PATTERN_DATE);
        // 加班日期集合
        ArrayList<String> dateList=new ArrayList<>();
        // 如果跨天,并且结束时间小于9点则加班日期不算最后一天
        while (true){
            dateList.add(startDate);
            // 开始时间和结束时间相等则出来
            if (Objects.equals(startDate,endDate)){
                break;
            }
            // 开始时间往后偏移一天
            startDate=DateUtil.dateOffSet(startDate,1);
        }
        return dateList;
    }

    /**
     * utc时间修改时间为东8区
     * @param date
     * @return
     */
    public static String modifyTime(String date) {
        Date oldDate = DateUtil.parseDate(date, DateUtil.PATTERN_DATE_TIME);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(oldDate);
        calendar.add(Calendar.HOUR_OF_DAY, +8);
        return DateUtil.calendarToDateStr(calendar);
    }

}
